package marcis.jarina.directory;

import org.apache.commons.collections.Predicate;

import java.io.File;
import java.io.FilenameFilter;

/**
 * @author jan.marcis
 */
public class MyFileFilter implements FilenameFilter {

    private final Predicate predicate;

    public MyFileFilter(Predicate predicate) {
        this.predicate = predicate;
    }

    @Override
    public boolean accept(File dir, String name) {
        return predicate.evaluate(new File(dir, name));
    }

    public static class PredicateFileType implements Predicate {

        public enum FILE_TYPE {
            DIRECTORY, FILE, NONE
        }

        private final FILE_TYPE file_type;

        public PredicateFileType(FILE_TYPE file_type) {
            this.file_type = file_type;
        }

        @Override
        public boolean evaluate(Object o) {
            File file = (File) o;
            return (file.isFile() && file_type.equals(FILE_TYPE.FILE)) ||
                    (file.isDirectory() && file_type.equals(FILE_TYPE.DIRECTORY)) ||
                    (!file.isFile() && !file.isDirectory() && file_type.equals(FILE_TYPE.NONE));
        }
    }

    public static class PredicateFileNameRegex implements Predicate {

        private final String regex;

        private String[] mustNotContain;

        public PredicateFileNameRegex(String reg) {
            this.regex = reg;

        }

        @Override
        public boolean evaluate(Object o) {
            File file = (File) o;
            boolean result = file.getName().matches(regex);
            if (mustNotContain != null) {
                for (String neStr : mustNotContain) {
                    result = result && !file.getName().contains(neStr);
                }
            }
            return result;
        }

        public void setMustNotContain(String[] mustNotContain) {
            this.mustNotContain = mustNotContain;
        }
    }

    public static class PredicateFileSize implements Predicate {

        private final Long minimum;

        private final Long maximum;

        public PredicateFileSize(Long minimum, Long maximum) {
            this.minimum = minimum;
            this.maximum = maximum;
        }

        @Override
        public boolean evaluate(Object o) {
            File file = (File) o;
            if (minimum == null && maximum == null) {
                return true;
            }
            long len = file.length();
            return minimum == null ? len < maximum : (maximum == null ? minimum < len : minimum < len && len < maximum);
        }
    }

}
